/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"
#include ".\listofports.h"

#include <algorithm>

//---------------------------------------------------------------------------

ListOfPorts::ListOfPorts(void)
{
}

ListOfPorts::~ListOfPorts(void)
{
	CleanUp();
}

//---------------------------------------------------------------------------

void ListOfPorts::CleanUp(void)
{
	theVector.clear();
}

//---------------------------------------------------------------------------

bool ListOfPorts::AddPort(WORD val)
{
	theVector.push_back(val);
//	theVector.insert(theVector.begin(), val);

	return true;
}

bool ListOfPorts::BuildPortRange(CString strIn, int* range, bool asPortIn)
{
	CString str, r1, r2;
	int swapper;
	int pos;

	str = strIn.Trim();

	if(str.CompareNoCase("*")==0){
		if(asPortIn){
			range[0] = 1;
			range[1] = 65535;
		}
		else{
			range[0] = 1;
			range[1] = 255;
		}
		return true;
	}

	pos = str.Find('-', 0);
	if(pos!=-1){
		r1 = strIn.Left(pos);
		r2 = strIn.Mid(pos+1);
	}
	else{
		r1 = strIn;
		r2 = strIn;
	}

	try{
		range[0] = _tstoi(r1);
	}
	catch(...)
	{
		return false;
	}

	try{
		range[1] = _tstoi(r2);
	}
	catch(...){
		return false;
	}

	if(range[0]>range[1]){
		swapper  = range[0];
		range[0] = range[1];
		range[1] = swapper;
	}

	return true;
}

bool ListOfPorts::AddPortFromString(CString strIn, bool addIt, bool asPortIn)
{
	int range[2];
	int val;

	if(strIn.IsEmpty()) return false;
	if(!BuildPortRange(strIn, &range[0], asPortIn)) return false;

	if(addIt){
		for(val=range[0]; val<=range[1]; val++){
			if(!AddPort((WORD)val))
				return false;
		}
	}
	else{
		reqSize += range[1] - range[0] + 1;
	}

	return true;
}

bool ListOfPorts::LoadFromString(CString strIn, bool asPortIn)
{
	CString str, sToken;
	int pos;

	CleanUp();

	reqSize = 0;

	str = strIn.Trim();
	while(!str.IsEmpty()){
		pos = str.Find(',', 0);
		if(pos==-1){
			sToken = str;
			str.Empty();
		}
		else{
			sToken = str.Left(pos);
			sToken = sToken.Trim();

			str = str.Mid(pos+1);
			str = str.Trim();
		}

		if(!AddPortFromString(sToken, false, asPortIn)) return false;
	}

	if(reqSize==0) return false;

	theVector.reserve(reqSize);

	str = strIn.Trim();
	while(!str.IsEmpty()){
		pos = str.Find(',', 0);
		if(pos==-1){
			sToken = str;
			str.Empty();
		}
		else{
			sToken = str.Left(pos);
			sToken = sToken.Trim();

			str = str.Mid(pos+1);
			str = str.Trim();
		}

		if(!AddPortFromString(sToken, true, asPortIn)) return false;
	}

	if(theVector.size()!=reqSize)
		return false;

	int rrr;
	rrr = (int)theVector.capacity();
	rrr = rrr;

	return true;
}

void ListOfPorts::Clear(void)
{
	CleanUp();
}

//---------------------------------------------------------------------------

int ListOfPorts::GetSize(void)
{
	return (int)theVector.size();
}

WORD ListOfPorts::GetFirst(void)
{
	if(theVector.size()==0) return 0;

	iter = theVector.begin();
	return *iter;
}

WORD ListOfPorts::GetNext(void)
{
	iter++;
	return *iter;
}

WORD ListOfPorts::GetByIdx(int idxIn)
{
	return theVector[idxIn];
}

//---------------------------------------------------------------------------

void ListOfPorts::SortTheList(void)
{
	std::sort(theVector.begin(), theVector.end());
}

void ListOfPorts::RandomizeList(void)
{
	std::random_shuffle(theVector.begin(), theVector.end());
}

//---------------------------------------------------------------------------

bool ListOfPorts::AddOnePort(WORD portIn)
{
	return AddPort(portIn);
}

//---------------------------------------------------------------------------
